﻿using EMoney.IStock.Client.DataAccess.Tclz;
using EMoney.IStock.Client.Framework;
using EMoney.IStock.Client.Models.Tclz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Dynamic;
using EMoney.IStock.Client.Models;

namespace EMoney.IStock.Client.Business.Tclz
{
    /// <summary>
    /// 题材领涨业务处理类
    /// </summary>
    public class TclzBll
    {
        private object objTclzDate = new object();
        private object objTclzList = new object();
        private object objTclzDetailList = new object();
        private object objTclzDetail = new object();
        private object objSuccessRate = new object();
        private object objTclzTotalNumber = new object();
        private object objTodayNumber = new object();
        private object objRecord = new object();

        private const string DATE_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.Date";
        private const string LIST_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.List";
        private const string DETAIL_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.Detail";
        private const string DETAILLIST_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.DetailList";
        private const string SUCCESSRATE_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.SuccessRate";
        private const string TOTALNUMBER_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.TotalNumber";
        private const string TODAYNUMBER_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.TodayNumber";
        private const string RECORD_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Tclz.TclzBll.Record";

        /// <summary>
        /// 获取近半年月份
        /// </summary>
        /// <returns></returns>
        public List<KeyValue> GetRecentMonth()
        {
            DateTime dtNow = DateTime.Now;
            string key = string.Concat(DATE_MEMCACHED_KEY, ".", StringHelper.FormatDateTime(dtNow));

            List<KeyValue> list = CacheManager.RedisCache.Get<List<KeyValue>>(key);

            if (list == null || list.Count == 0)
            {
                lock (objTclzDate)
                {
                    list = CacheManager.RedisCache.Get<List<KeyValue>>(key);

                    if (list == null || list.Count == 0)
                    {
                        DateTime dtMax = dtNow;
                        DateTime dtMin = dtNow.AddMonths(-6);
                        string value = string.Empty;
                        list = new List<KeyValue>();

                        while (!StringHelper.FormatDateTime(dtMin.Date,"yyyyMM").Equals(StringHelper.FormatDateTime(dtMax.Date,"yyyyMM"),StringComparison.OrdinalIgnoreCase))
                        {
                            list.Add(new KeyValue()
                            {
                                key = StringHelper.FormatDateTime(dtMax, "yyyyMM"),
                                value = string.Concat(StringHelper.FormatDateTime(dtMax, "yyyy年M月"))
                            });

                            dtMax = dtMax.AddMonths(-1);
                        }

                        CacheManager.DefaultCache.Set<List<KeyValue>>(key, list, 60 * 24);
                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 获取指定区间 题材优选 个股信息
        /// </summary>
        /// <param name="dtBegin"></param>
        /// <param name="dtEnd"></param>
        /// <returns></returns>
        public List<VM_CHASE_STK_LIST> GetList(DateTime dtBegin, DateTime dtEnd)
        {
            string key = string.Concat(LIST_MEMCACHED_KEY, ".", dtBegin.ToString("yyyy-MM-dd"), ".", dtEnd.AddDays(1).ToString("yyyy-MM-dd"));

            List<VM_CHASE_STK_LIST> list = CacheManager.RedisCache.Get<List<VM_CHASE_STK_LIST>>(key);

            if (list == null)
            {
                try
                {
                    lock (objTclzList)
                    {
                        list = CacheManager.RedisCache.Get<List<VM_CHASE_STK_LIST>>(key);

                        if (list == null)
                        {
                            TclzDal dal = new TclzDal();

                            list = dal.GetList(dtBegin.Date, dtEnd.AddDays(1).Date);

                            if (list == null)
                            {
                                list = new List<VM_CHASE_STK_LIST>();
                            }

                            foreach (VM_CHASE_STK_LIST stk in list)
                            {
                                stk.DateTxt = StringHelper.FormatDateTimeNew(stk.DATE);
                                stk.ListDetail = dal.GetDetail(stk.SecuCode, stk.standard, dtBegin.Date, dtEnd.AddDays(1).Date, stk.DATE.ToString("yyyy-MM-dd"));

                                if (stk.ListDetail != null && stk.ListDetail.Count > 0)
                                {
                                    bool boolFlag = false;
                                    foreach (VM_CHASE_STK_DETAIL detail in stk.ListDetail)
                                    {
                                        boolFlag = false;
                                        detail.REASON = StringHelper.StringSubstrLen(detail.REASON, 42);

                                        if (detail.DATE.DayOfWeek == DayOfWeek.Friday)  //周五
                                        {
                                            if (DateTime.Now.Date >= detail.DATE.AddDays(4).Date)
                                            {
                                                boolFlag = true;
                                            }
                                        }
                                        else
                                        {
                                            if (DateTime.Now.Date >= detail.DATE.AddDays(2).Date)
                                            {
                                                boolFlag = true;
                                            }
                                        }

                                        if (boolFlag)
                                        {
                                            switch (detail.FLAG)
                                            {
                                                case "0":
                                                    detail.FlagText = "异动后处于下跌趋势";
                                                    break;
                                                case "1":
                                                    detail.FlagText = string.Concat("至", StringHelper.FormatDateTime(detail.TOTALRISEDATE), "，最高涨幅达 <span style='color:#FF5244;'>", StringHelper.FormatDecimal(detail.CLOSERISE * 100), "%</span>");
                                                    break;
                                                default:
                                                    detail.FlagText = "--";
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            detail.FlagText = "--";
                                        }
                                    }
                                }
                            }

                            CacheManager.DefaultCache.Set<List<VM_CHASE_STK_LIST>>(key, list, 60);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取指定区间 题材领涨 个股信息失败");
                }
            }

            return list;
        }

        /// <summary>
        /// 获取指定区间、指定关键字 题材优选 详情列表
        /// </summary>
        /// <param name="secucode"></param>
        /// <param name="standard"></param>
        /// <param name="dtBegin"></param>
        /// <param name="dtEnd"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public List<VM_CHASE_STK_DETAIL> GetDetailList(string secucode, string standard, DateTime dtBegin, DateTime dtEnd, string time)
        {
            string key = string.Concat(DETAILLIST_MEMCACHED_KEY, ".", secucode, ".", standard, ".", dtBegin.ToString("yyyy-MM-dd"), ".", dtEnd.AddDays(1).ToString("yyyy-MM-dd"));

            List<VM_CHASE_STK_DETAIL> listDetail = CacheManager.RedisCache.Get<List<VM_CHASE_STK_DETAIL>>(key);

            if (listDetail == null)
            {
                try
                {
                    lock (objTclzDetailList)
                    {
                        listDetail = CacheManager.RedisCache.Get<List<VM_CHASE_STK_DETAIL>>(key);

                        if (listDetail == null)
                        {
                            TclzDal dal = new TclzDal();

                            listDetail = dal.GetDetail(secucode, standard, dtBegin.Date, dtEnd.AddDays(1).Date, time);

                            if (listDetail == null)
                            {
                                listDetail = new List<VM_CHASE_STK_DETAIL>();
                            }

                            CacheManager.DefaultCache.Set<List<VM_CHASE_STK_DETAIL>>(key, listDetail, 60);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取指定区间、指定关键字 题材领涨 详情列表失败");
                }
            }

            return listDetail;
        }

        /// <summary>
        /// 获取指定区间、指定关键字 题材优选 详情信息(除当前股票以外)
        /// </summary>
        /// <param name="secucode"></param>
        /// <param name="standard"></param>
        /// <param name="dtBegin"></param>
        /// <param name="dtEnd"></param>
        /// <returns></returns>
        public string GetDetail(string secucode, string standard, DateTime dtBegin, DateTime dtEnd, string time)
        {
            string key = string.Concat(DETAIL_MEMCACHED_KEY, ".", secucode, ".", standard, ".", dtBegin.ToString("yyyy-MM-dd"), ".", dtEnd.AddDays(1).ToString("yyyy-MM-dd"));

            string strDetail = CacheManager.RedisCache.Get<string>(key);

            if (string.IsNullOrEmpty(strDetail))
            {
                try
                {
                    lock (objTclzDetail)
                    {
                        TclzDal dal = new TclzDal();

                        List<VM_CHASE_STK_DETAIL> listDetail = dal.GetDetail(secucode, standard, dtBegin.Date, dtEnd.AddDays(1).Date, time);

                        if (listDetail == null)
                        {
                            listDetail = new List<VM_CHASE_STK_DETAIL>();
                        }

                        strDetail = JsonHelper.ToJson(listDetail);

                        CacheManager.DefaultCache.Set<string>(key, strDetail, 60);
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取指定区间、指定关键字 题材领涨 详情信息(除当前股票以外)失败");
                }
            }

            return strDetail;
        }

        /// <summary>
        /// 获取成功率信息
        /// </summary>
        /// <returns></returns>
        public List<CHASE_SUCCESSRATE> GetSuccessRate()
        {
            List<CHASE_SUCCESSRATE> list = CacheManager.RedisCache.Get<List<CHASE_SUCCESSRATE>>(SUCCESSRATE_MEMCACHED_KEY);

            if (list == null)
            {
                try
                {
                    lock (objSuccessRate)
                    {
                        list = CacheManager.RedisCache.Get<List<CHASE_SUCCESSRATE>>(SUCCESSRATE_MEMCACHED_KEY);

                        if (list == null)
                        {
                            TclzDal dal = new TclzDal();

                            list = dal.GetSuccessRate();

                            if (list == null)
                            {
                                list = new List<CHASE_SUCCESSRATE>();
                            }

                            CacheManager.DefaultCache.Set<List<CHASE_SUCCESSRATE>>(SUCCESSRATE_MEMCACHED_KEY, list, 60);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取题材领涨成功率信息失败");
                }
            }

            return list;
        }

        /// <summary>
        /// 获取指定区间内异动股票总个数
        /// </summary>
        /// <param name="dtBegin"></param>
        /// <param name="dtEnd"></param>
        /// <returns></returns>
        public int GetTotalNumber(DateTime dtBegin, DateTime dtEnd)
        {
            string key = string.Concat(TOTALNUMBER_MEMCACHED_KEY, ".", dtBegin.ToString("yyyy-MM-dd"), ".", dtEnd.AddDays(1).ToString("yyyy-MM-dd"));

            string totalNumber = CacheManager.RedisCache.Get<string>(key);

            if (string.IsNullOrEmpty(totalNumber))
            {
                try
                {
                    lock (objTclzTotalNumber)
                    {
                        totalNumber = CacheManager.RedisCache.Get<string>(key);

                        if (string.IsNullOrEmpty(totalNumber))
                        {
                            TclzDal dal = new TclzDal();

                            int intTotalNumber = dal.GetTotalNumber(dtBegin.Date, dtEnd.AddDays(1).Date);

                            CacheManager.DefaultCache.Set<string>(key, intTotalNumber.ToString(), 60);

                            return intTotalNumber;
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取题材领涨指定区间内异动股票总个数失败");
                }
            }

            return Convert.ToInt32(totalNumber);
        }

        /// <summary>
        /// 获取今日异动股票数量
        /// </summary>
        /// <returns></returns>
        public int GetTodayNumber()
        {
            string todayNumber = CacheManager.RedisCache.Get<string>(TODAYNUMBER_MEMCACHED_KEY);

            if (string.IsNullOrEmpty(todayNumber))
            {
                try
                {
                    lock (objTodayNumber)
                    {
                        todayNumber = CacheManager.RedisCache.Get<string>(TODAYNUMBER_MEMCACHED_KEY);

                        if (string.IsNullOrEmpty(todayNumber))
                        {
                            TclzDal dal = new TclzDal();

                            int intTodayNumber = dal.GetTodayNumber();

                            CacheManager.DefaultCache.Set<string>(TODAYNUMBER_MEMCACHED_KEY, intTodayNumber.ToString(), 60);

                            return intTodayNumber;
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取题材领涨今日异动股票数量失败");
                }
            }

            return Convert.ToInt32(todayNumber);
        }

        /// <summary>
        /// 获取一年半以来策略战绩
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public List<VM_CHASE_STK_LIST> GetRecord(string sortFlag, string sortType)
        {
            DateTime date = DateTime.Now.AddDays(-180);
            string key = string.Concat(RECORD_MEMCACHED_KEY, ".", date.ToString("yyyy-MM-dd"));

            List<VM_CHASE_STK_LIST> listRecord = CacheManager.RedisCache.Get<List<VM_CHASE_STK_LIST>>(key);

            if (listRecord == null)
            {
                try
                {
                    lock (objRecord)
                    {
                        listRecord = CacheManager.RedisCache.Get<List<VM_CHASE_STK_LIST>>(key);

                        if (listRecord == null)
                        {
                            TclzDal dal = new TclzDal();

                            listRecord = dal.GetRecord(date);

                            if (listRecord == null)
                            {
                                listRecord = new List<VM_CHASE_STK_LIST>();
                            }
                        }

                        CacheManager.DefaultCache.Set<List<VM_CHASE_STK_LIST>>(key, listRecord, 60);
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取题材领涨一年半以来策略战绩失败");
                }
            }

            if (listRecord != null && listRecord.Count > 0)
            {
                listRecord = listRecord.AsQueryable().OrderBy(string.Concat(sortFlag, " ", sortType)).ToList();
            }

            return listRecord;
        }
    }
}
